home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
JCSM Shareware Collection 1993 November
/
JCSM Shareware Collection - 1993-11.iso
/
cl720
/
sst115j.lzh
/
SSTVID.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-18
|
21KB
|
670 lines
/* ------------------------------------------------------------------------ */
/* sstvid.c */
/* */
/* low-level video functions */
/* */
/* CopyRight (C) 1991,1992 Steven Lutrov. All rights reserved. */
/* ------------------------------------------------------------------------ */
#include <dos.h>
#include <bios.h>
#include <stdio.h>
#include <stdarg.h>
#include <alloc.h>
#include <string.h>
#include "sstvid.h"
/* ------------------------------------------------------------------------ */
/* video BIOS (0x10) functions */
/* ------------------------------------------------------------------------ */
#define SETCURSORTYPE 0x01
#define SETCURSOR 0x02
#define READCURSOR 0x03
#define READATTRCHAR 0x08
#define WRITEATTRCHAR 0x09
#define HIDECURSOR 0x20
#define ZEROFLAG 0x40 /* zero flag mask */
#define MAXCSAVES 50 /* maximun cursor saves */
#define MAXSSAVES 12 /* maximun screen saves */
#define VIDSEGREG (unsigned)((7 == VIDMODE) ? 0xb000 : 0xb800 )
#define SCRSIZE (SCREENWIDTH * SCREENHEIGHT * 2)
/* ------------------------------------------------------------------------ */
/* local prototypes */
/* ------------------------------------------------------------------------ */
static void near getcursor (void);
static void scan350 (void);
static void scan400 (void);
static void getvmode (void);
static unsigned char far *currentpos (void);
static unsigned char far *scrptr (int x, int y);
/* ------------------------------------------------------------------------ */
/* local variables */
/* ------------------------------------------------------------------------ */
static int near cursorpos[MAXCSAVES]; /* cursor position buffer */
static int near cursorshape[MAXCSAVES]; /* cursor shape buffer */
static int cs = 0; /* cursor save counter */
static char far *scrarray[MAXSSAVES];
static int ss = -1; /* screen save counter */
unsigned int vmode; /* video mode */
unsigned int vpage; /* video page number */
/* ------------------------------------------------------------------------ */
/* clear the screen in a given attribute by scrolling */
/* ------------------------------------------------------------------------ */
void vcls(unsigned char attr)
{
_AH = 0x06; /* scroll window up */
_AL = 0; /* clear entire window */
_BH = attr;
_CX = 0; /* upper left = (0,0) */
_DH = SCREENHEIGHT-1;
_DL = SCREENWIDTH-1;
geninterrupt(VIDEO);
}
/* ------------------------------------------------------------------------ */
/* clear a given line */
/* ------------------------------------------------------------------------ */
void vclearline(unsigned char row, unsigned char attr)
{
_AH = 0x06; /* scroll window up */
_AL = 1; /* clear 1 line */
_BH = attr;
_CH = row; /* upper left = (row,0) */
_CL = 0;
_DH = row; /* lower right = (row,79) */
_DL = SCREENWIDTH-1;
geninterrupt(VIDEO);
}
/* ------------------------------------------------------------------------ */
/* position the cursor */
/* ------------------------------------------------------------------------ */
void vsetcur(int x, int y)
{
getvmode();
_DX = ((y << 8) & 0xFF00) + x;
_AH = SETCURSOR;
_BX = vpage;
geninterrupt(VIDEO);
}
/* ------------------------------------------------------------------------ */
/* return the current cursor position */
/* ------------------------------------------------------------------------ */
void vgetcur(int *x, int *y)
{
getcursor();
*x = _DL;
*y = _DH;
}
/* ------------------------------------------------------------------------ */
/* use BIOS set cursor type */
/* ------------------------------------------------------------------------ */
void vsetcurtype(unsigned t)
{
getvmode();
_AH = SETCURSORTYPE;
_BX = vpage;
_CX = t;
geninterrupt(VIDEO);
}
/* ------------------------------------------------------------------------ */
/* test for scroll lock */
/* ------------------------------------------------------------------------ */
int Kscrolllock()
{
_AX = 0x0200;
geninterrupt(VIDEO);
return _AL & 0x10;
}
void (*helpfunc)(void); /* function prototype */
int helpkey = 0;
int helping = 0;
/* ------------------------------------------------------------------------ */
/* get a keyboard character and hooks help if help is required */
/* ------------------------------------------------------------------------ */
unsigned int kgetch(void)
{
unsigned int c;
while (1) {
_AH = 0x01;
geninterrupt(KEYBRD);
if (_FLAGS & 0x40) {
geninterrupt(KBUSYLOOP);
continue;
}
_AH = 0x00;
geninterrupt(KEYBRD);
c = (_AL > 0 && _AL < 127) ? _AL : _AX;
if (c == helpkey && helpfunc) {
if (!helping) {
helping = 1;
(*helpfunc)();
helping = 0;
continue;
}
}
break;
}
return c;
}
/* ------------------------------------------------------------------------ */
/* get a keyboard char (extended kbd) and hooks help if help is required */
/* ------------------------------------------------------------------------ */
unsigned int kgetche(void)
{
unsigned int c;
while (1) {
_AH = 0x11;
geninterrupt(KEYBRD);
if (_FLAGS & ZEROFLAG) {
geninterrupt(KBUSYLOOP);
continue;
}
_AH = 0x10;
geninterrupt(KEYBRD);
c = (_AL > 0 && _AL < 127) ? _AL : _AX;
if (c == helpkey && helpfunc) {
if (!helping) {
helping = 1;
(*helpfunc)();
helping = 0;
continue;
}
}
break;
}
return c;
}
/* ------------------------------------------------------------------------ */
/* Test for keystroke */
/* ------------------------------------------------------------------------ */
int kkeyhit(void)
{
_AH = 0x11;
geninterrupt(KEYBRD);
return (_FLAGS & ZEROFLAG) == 0;
}
/* ------------------------------------------------------------------------ */
/* save the current cursor configuration */
/* ------------------------------------------------------------------------ */
void vpushcur(void)
{
if (cs < MAXCSAVES) {
getcursor();
cursorshape[cs] = _CX;
cursorpos[cs] = _DX;
cs++;
}
}
/* ------------------------------------------------------------------------ */
/* restore the saved cursor configuration */
/* ------------------------------------------------------------------------ */
void vpopcur(void)
{
if (cs) {
--cs;
getvmode();
_DX = cursorpos[cs];
_AH = SETCURSOR;
_BX = vpage;
geninterrupt(VIDEO);
vsetcurtype(cursorshape[cs]);
}
}
/* ------------------------------------------------------------------------ */
/* make a normal cursor */
/* ------------------------------------------------------------------------ */
void vnormalcur(void)
{
vsetcurtype(0x0607);
}
/* ------------------------------------------------------------------------ */
/* hide the cursor */
/* ------------------------------------------------------------------------ */
void vhidecur(void)
{
getcursor();
_CH |= HIDECURSOR;
_AH = SETCURSORTYPE;
geninterrupt(VIDEO);
}
/* ------------------------------------------------------------------------ */
/* unhide the cursor */
/* ------------------------------------------------------------------------ */
void vshowcur(void)
{
getcursor();
_CH &= ~HIDECURSOR;
_AH = SETCURSORTYPE;
geninterrupt(VIDEO);
}
/* ------------------------------------------------------------------------ */
/* test for EGA */
/* ------------------------------------------------------------------------ */
int visega(void)
{
if (visvga())
return 0;
_AH = 0x12;
_BL = 0x10;
geninterrupt(VIDEO);
return (_BL != 0x10);
}
/* ------------------------------------------------------------------------ */
/* test for VGA */
/* ------------------------------------------------------------------------ */
int visvga(void)
{
_AX = 0x1a00;
geninterrupt(VIDEO);
return _AL == 0x1A && _BL > 6;
}
/* ------------------------------------------------------------------------ */
/* set 25 line mode */
/* ------------------------------------------------------------------------ */
void vset25(void)
{
if (visvga())
scan400();
_AX = (visvga() ? 0x1114 : 0x1111);
_BX = 0;
geninterrupt(VIDEO);
}
/* ------------------------------------------------------------------------ */
/* set 43 line mode */
/* ------------------------------------------------------------------------ */
void vset43(void)
{
if (visvga())
scan350();
_AX = 0x1112;
_BX = 0;
geninterrupt(VIDEO);
}
/* ------------------------------------------------------------------------ */
/* set 50 line mode */
/* ------------------------------------------------------------------------ */
void vset50(void)
{
if (visvga())
scan400();
_AX = 0x1112;
_BX = 0;
geninterrupt(VIDEO);
}
/* ------------------------------------------------------------------------ */
/* Toggle intensity/blinking bit */
/* ------------------------------------------------------------------------ */
void vblinkbit(int f) /* NOTE - only valid for EGA/VGA systems */
{
_BL = f;
_BH = 0;
_AX = 0x1003;
geninterrupt(VIDEO);
}
int far *kbd_status = (int far *) 0x00000417L;
/* ------------------------------------------------------------------------ */
/* return the state of all the keys by peeking into bios */
/* ------------------------------------------------------------------------ */
int far *kstate(void)
{
return (kbd_status);
}
/* ------------------------------------------------------------------------ */
/* put a char and attribute at the given coordinates */
/* ------------------------------------------------------------------------ */
void vputch(int x, int y, unsigned char a, register unsigned char c)
{
register unsigned char far *p;
p = scrptr(x,y);
*p++ = c;
*p++ = a;
}
/* ------------------------------------------------------------------------ */
/* put a string at the given coordinates */
/* ------------------------------------------------------------------------ */
void vputs(int x, int y, unsigned char a, register char *s )
{
register unsigned char far *p;
p = scrptr(x,y);
while (*s) {
*p++ = *s++;
*p++ = a;
}
}
/* ------------------------------------------------------------------------ */
/* put a formatted string at the given coordinates */
/* ------------------------------------------------------------------------ */
void vputf( int x, int y, unsigned char a, char *fmt, ... )
{
register unsigned char far *p;
char s[120];
register char *cp = s;
va_list argptr;
va_start( argptr, fmt );
vsprintf( s, fmt, argptr );
va_end( argptr );
p = scrptr(x,y);
while (*cp) {
*p++ = *cp++;
*p++ = a;
}
}
/* ------------------------------------------------------------------------ */
/* put a string centered on a given line */
/* ------------------------------------------------------------------------ */
void vputsc( int y, unsigned char a, char *s )
{
vputs ( ( 80 - strlen(s) ) / 2, y, a, s );
}
/* ------------------------------------------------------------------------ */
/* put a formatted and centered string at the given coordinates */
/* ------------------------------------------------------------------------ */
void vputfc(int y, unsigned char a, char *fmt, ... )
{
char s[120];
va_list ap;
va_start( ap, fmt );
vsprintf( s, fmt, ap );
va_end( ap );
vputs( ( 80 - strlen(s) ) / 2, y, a, s );
}
/* ------------------------------------------------------------------------ */
/* return the attribute at the given coordinates */
/* ------------------------------------------------------------------------ */
int vgeta(int x, int y)
{
unsigned char far *p;
p = scrptr(x,y);
return(*(++p));
}
/* ------------------------------------------------------------------------ */
/* return the character at the given coordinates */
/* ------------------------------------------------------------------------ */
int vgetch(int x, int y)
{
unsigned char far *p;
p = scrptr(x,y);
return(*p++);
}
/* ------------------------------------------------------------------------ */
/* return the character and attribute at the given coordinates */
/* ------------------------------------------------------------------------ */
int vget(int x, int y)
{
int far *p;
p = (int far*) scrptr(x,y);
return(*p++);
}
/* ------------------------------------------------------------------------ */
/* return the attribute at the current cursor coordinates */
/* ------------------------------------------------------------------------ */
int vgetac(void)
{
unsigned char far *scptr = currentpos();
return( *(++scptr));
}
/* ------------------------------------------------------------------------ */
/* returns the char at the current cursor coordinates */
/* ------------------------------------------------------------------------ */
int vgetchc(void)
{
unsigned char far *scptr = currentpos();
return (*scptr);
}
/* ------------------------------------------------------------------------ */
/* fills an area of the screen with a given char and attribute */
/* ------------------------------------------------------------------------ */
void vfill(int x, int y, int yy, int xx, int c, int a)
{
char s[80];
memset(s,c,80);
s[xx] = '\00';
while (yy)
vputs(x,y-1+(yy--),a,s);
}
/* ------------------------------------------------------------------------ */
/* pushes the screen contents to the far stack */
/* ------------------------------------------------------------------------ */
int vpushscreen(void)
{
if ( ++ss > 15 ) {
ss--;
return(-1);
}
if ( (scrarray[ss] = (char far *)farmalloc(SCRSIZE) ) == NULL )
return(-2);
movedata(VIDSEGREG, 0, FP_SEG(scrarray[ss]),
FP_OFF(scrarray[ss]), 4000);
return(0);
}
/* ------------------------------------------------------------------------ */
/* pops the screen contents of the far stack */
/* ------------------------------------------------------------------------ */
void vpopscreen(void)
{
movedata(FP_SEG(scrarray[ss]), FP_OFF(scrarray[ss]),
VIDSEGREG, 0, SCRSIZE);
farfree(scrarray[ss]);
ss--;
}
/* ------------------------------------------------------------------------ */
/* get cursor shape and position */
/* ------------------------------------------------------------------------ */
static void near getcursor(void)
{
getvmode();
_AH = READCURSOR;
_BX = vpage;
geninterrupt(VIDEO);
}
/* ------------------------------------------------------------------------ */
/* interrupt to produce 350 scan lines */
/* ------------------------------------------------------------------------ */
static void scan350(void)
{
_AX = 0x1201;
_BL = 0x30;
geninterrupt(VIDEO);
}
/* ------------------------------------------------------------------------ */
/* interrupt to produce 400 scan lines */
/* ------------------------------------------------------------------------ */
static void scan400(void)
{
_AX = 0x1202;
_BL = 0x30;
geninterrupt(VIDEO);
}
/* ------------------------------------------------------------------------ */
/* get the video mode and page from BIOS */
/* ------------------------------------------------------------------------ */
static void getvmode(void)
{
_AH = 15;
geninterrupt(VIDEO);
vmode = _AL;
vpage = _BX;
vpage &= 0xFF00;
vmode &= 0x7F;
}
/* ------------------------------------------------------------------------ */
/* return the current curosr position */
/* ------------------------------------------------------------------------ */
static unsigned char far *currentpos (void)
{
_AH = 0x03;
_BX = 0x00;
geninterrupt(VIDEO);
return (scrptr( _DL+1, _DH+1 ) );
}
/* ------------------------------------------------------------------------ */
/* returns the video address for the given coordinates */
/* ------------------------------------------------------------------------ */
static unsigned char far *scrptr (int x, int y)
{
return (VIDSEG + (y * (SCREENWIDTH*2)) + (x << 1) );
}
/* ------------------------------------------------------------------------ */
/* puts the current date out to the screen */
/* 1 = dd-mm-yy 2 = dd mmm yyyy 3 = mm-dd-yy 4 = yy-mm-dd */
/* ------------------------------------------------------------------------ */
void vputdate(int x, int y, int attr, int fmt )
{
char *MonthArray[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
struct date dt;
getdate(&dt);
switch(fmt) {
case 1:
vputf(x, y, attr,"%2d-%02d-%02d", dt.da_day, dt.da_mon,
dt.da_year % 100 );
break;
case 2:
vputf(x, y, attr,"%2d %3s %04d", dt.da_day,
MonthArray[dt.da_mon-1], dt.da_year );
break;
case 3:
vputf(x, y, attr,"%02d-%2d-%02d", dt.da_mon, dt.da_day,
dt.da_year % 100 );
break;
case 4:
vputf(x, y, attr,"%02d-%02d-%2d", dt.da_year % 100 , dt.da_mon,
dt.da_day);
break;
}
}
/* ------------------------------------------------------------------------ */
/* puts the current time onto the screen */
/* 1 = hh:mm:ss (military) 2 = hh:mm (military) */
/* 3 = hh:mm:ss AM/PM 4 = hh:mm AM/PM */
/* ------------------------------------------------------------------------ */
void vputtime(int x, int y, int attr, int fmt)
{
struct time tm;
char c;
gettime(&tm);
switch(fmt) {
case 1:
vputf(x, y, attr,"%2d:%02d:%02d",
tm.ti_hour, tm.ti_min, tm.ti_sec );
break;
case 2:
vputf(x, y, attr,"%2d:%02d",tm.ti_hour, tm.ti_min );
break;
case 3:
c = 'A';
if ( tm.ti_hour > 11 ) {
c = 'P';
tm.ti_hour -= 12;
}
if ( tm.ti_hour == 0 ) tm.ti_hour = 12;
vputf(x, y, attr,"%2d:%02d:%02d %cM",
tm.ti_hour, tm.ti_min, tm.ti_sec, c );
break;
case 4:
c = 'A';
if ( tm.ti_hour > 11 ) {
c = 'P';
tm.ti_hour -= 12;
}
if ( tm.ti_hour == 0 ) tm.ti_hour = 12;
vputf(x, y, attr,"%2d:%02d %cM",
tm.ti_hour, tm.ti_min, c );
break;
}
}
/* ------------------------------------------------------------------------ */
/* makes a beep noise */
/* ------------------------------------------------------------------------ */
void vbeep(int m)
{
if (m) {
sound(2000);
delay(100);
}
else {
sound(500);
delay(250);
}
nosound();
}